# coding=utf-8 

# 为了符合业务需要，将淘宝sdk源码进行更改，更改内容为api/base.py 中的94行，可以直接传入字符流
# 具体执行如下操作, vim top/api/base.py, 修改94行代码 
# 将 body = fileHandle.read()
# 修改为：
# try:
#     body = fileHandle.read()
# except:
#     body = fileHandle



import top.api
import json
import sys 
import time
import gevent
import Setting
import requests
import redis
from socket import *
from gevent import monkey; monkey.patch_all()

reload(sys) # Python2.5 初始化后删除了 sys.setdefaultencoding 方法，我们需要重新载入 
sys.setdefaultencoding('utf-8') 


url = 'http://gw.api.taobao.com/router/rest'
port = '80'

# 向淘宝上传图片并接收返回值
def put_top(sessionkey, wait, wait_byte):
    
    # 以下是淘宝SDK逻辑，没完全搞清楚，现在能用
    appkey = '23656735'
    secret = '91400648c84ddd33f32dd9181d5f14c8'
    req=top.api.PictureUploadRequest()
    req.set_app_info(top.appinfo(appkey,secret)) 
    
    
    image_name = wait[0]
    image_byte = wait[1]
    num = image_name
    #print(sessionkey)
    #sessionkey = '620163013d9609e8f5f21493d38367fd85d199ZZ36b8acc117760830'
    print "##"*40
    print sessionkey
    print num, '正在高速上传'
    req.picture_category_id='0'
    

    req.img=top.api.FileItem('abc.jpg', image_byte)
    req.image_input_title="Bule.jpg"
    req.title="图片名称"
    #req.picture_id=10000
    req.client_type="client:computer"
    #req.is_https= False

    timeout = 0
    while True:
        try:
            start = time.time()
            resp= req.getResponse(sessionkey)
            print num, '执行完毕', '上传次数:', timeout, ' start:', start, 'end:', time.time()
            
            with open("./hmm2.txt",'a') as json_file:
                json_file.write(json.dumps(resp) +'\n')
                
            wait[1] = resp['picture_upload_response']['picture']['picture_path']
            wait.append(str(resp['picture_upload_response']['picture']['picture_id']))
            print "#"*100
            print wait
            wait_byte.append(wait)
            
            return 
        
        except Exception as e:
            print(e)
            timeout += 1
            if timeout > 5:
                print '上传超限制，强制结束上传'
                return False
            print '上传失败，尝试重新上传,目前失败次数:', timeout
       
def get_image_run(wait, image_byte):
    """配合ｇｅｖｅｎｔ下载"""
    
    timeout = 0
    while True:
        try:
            print wait[0], '图片高速下载中, 下载次数:', timeout 
            images = requests.get(wait[1],  verify=False).content
            wait[1] = images
            print wait[0], '图片高速下载完毕, 共下载次数 ', timeout+1
            image_byte.append(wait)
            return 
        except Exception as e:
            print(e)
            timeout += 1
            print wait[0], '图片下载失败,重新下载，当前下载次数：', timeout
            if timeout > 5:
                print wait[0], '图片此案在超过上限，请检查链接:', wait[1]
                return False


def get_image_byte(image_url, image_byte):
    """获取图片字节流"""
    
    # 执行队列
    get_image = list()
    for _ in image_url:
        get_image.append(gevent.spawn(get_image_run, _, image_byte))
        print _[0] ,'待下载图片高速入队列'
    
    gevent.joinall(get_image)





# 执行函数
def run(sessionkey, goods_id, image_url):
    #show = put_top(req,sessionkey, 'timg.jpeg', image_type)
    
    
    image_byte = list()  # 接收返回值
    get_image_byte(image_url, image_byte)

    wait_byte = list()  # 接收返回值

    # 设置并发上限 
    pu_image_max = 0
    wait_list = list()  # 执行列表

    start = time.time()
    for _ in image_byte:

        wait_list.append(gevent.spawn(put_top, sessionkey, _, wait_byte))
        pu_image_max += len(_[1])
        if pu_image_max >= Setting.size:
            gevent.joinall(wait_list)
            pu_image_max = 0
            wait_list = list()  # 执行列表和待发送大小同时清空
        

    if wait_list:  #  如果等待列表里有数据则将剩余数据上传
        gevent.joinall(wait_list)

    print '上传共用时:', time.time() - start
    print wait_byte
    info_dict = dict()
    for _ in wait_byte:
        info_dict[_[0]] = _[1]
        info_dict['picture_id'] = _[2]
    return info_dict



def inform_api(goods_id, end_dict, client_tcp):
    """把数据存到ｒｅｄｉｓ里然后通知ｗｅｂ网站告诉他完成"""

    picture_id = end_dict.pop('picture_id')
    data = 'goods,' + str(goods_id)
    data = data.encode('utf-8')
    client_tcp.send(data)
    print '发送', data

    data = 'pictureid,'+ picture_id
    data = data.encode('utf-8')
    client_tcp.send(data)

   # r = redis.StrictRedis(host='localhost', port=6379, db=0)
   # r.hmset("EndUpProduct_"+goods_id ,end_dict)
   # r.lpush('delpicidlist', picture_id)
   # response = requests.get(Setting.api+goods_id)
    while True:
        for key, value in end_dict.items():
            data = 'id,' + key + ',' + value
            data = data.encode('utf-8')
            client_tcp.send(data)
            #client_tcp.recv(1024)
        return

    print response


def main():

    # 目的信息
    server_ip = Setting.ServerIp
    server_port = Setting.ServerPort
    
    while True:
        start = time.time()
        # 创建socket
        tcp_client_socket = socket(AF_INET, SOCK_STREAM)

        print '正在链接服务器'
        # 链接服务器
        tcp_client_socket.connect((server_ip, server_port))
        print '服务器链接成功 '
        wait_task = str()
        while True:
            # 接收对方发送过来的数据，最大接收1024个字节
            recvData = tcp_client_socket.recv(1024)
            recvData = recvData.decode('utf-8')
            if recvData == "not task":
                print recvData
                time.sleep(0.3)
                send_data = 'give task'
                tcp_client_socket.send(send_data.encode("utf-8"))

            else:
                print recvData
                if recvData == 'sendend':  # 如果发送完毕则会发送一个sendend命令
                    break
                else:
                    wait_task = wait_task + recvData  #　拼接任务
                    
                    # 提示服务器收到任务请继续发送
                    send_data = 'ok'
                    tcp_client_socket.send(send_data.encode("utf-8"))
        
        # 接收完整任务之后则开始准备执行任务数据,目前拼接的数据是这样的: "key:@:value, key:@:value......"
        wait_task = wait_task.split(',')
        print(wait_task)
        # 组装数据
        sessionkey = str()
        image_url = list()
        goods_id = str
        for _ in wait_task:
            info = _.split(':@:')
            if info[0] == 'Sessinkey':
                sessionkey = info[1] 
            elif info[0] == "id":
                goods_id = info[1]
            else:
                image_url.append(info)
        print(1)
        # 调动上传函数
        end_dict = run(sessionkey, goods_id, image_url)
        print(2)
        # 给目标ａｐｉ进行反馈
        inform_api(goods_id, end_dict, tcp_client_socket)

        # 关闭套接字
        tcp_client_socket.close()
        print '任务执行完毕', goods_id

        with open('work执行log.txt','a') as f:
            f.write('商品id:'+goods_id+'执行完毕,开始时间：'+str(start)+'共用时：'+str(time.time()-start)+'\n\n\n')







if __name__ == '__main__':
    main()







  
